np
<!--
*@Author: QWP
*@Description: 登录页面
*@Date: 2024-07-13 09:10:13
-->
<template>
  <a-layout
    class="f-h-100 u-login-container"
    :style="{ backgroundImage: `url(${loginBg.img})` }"
    @keydown.enter.native="logingSubmit">
    <a-layout-content style="padding: 0">
      <a-row
        :gutter="13"
        style="padding: 0.75rem; margin: 0">
        <a-col :span="24">
          <span
            class="u-sys-name-zh"
            :style="{ '--snc': loginBg.snc }">
            {{ sysName }}
          </span>
        </a-col>
        <a-col :span="24">
          <span class="u-sys-name-en">
            Emergency system collaborative office platform
          </span>
        </a-col>
      </a-row>
      <div :class="loginBg.loginClass">
        <a-row>
          <a-space
            :size="30"
            class="f-padding-b40">
            <div
              class="u-login-type-title"
              :class="{ 'u-login-type-title-active': loginType == '1' }"
              @click="loginType = 1">
              短信登录
            </div>
            <div
              class="u-login-type-title"
              :class="{ 'u-login-type-title-active': loginType == '2' }"
              @click="loginType = 2">
              账号登录
            </div>
          </a-space>
        </a-row>

        <!-- 账号表单 -->
        <u-form
          :elements="loginFormEls"
          v-if="loginType == 2"
          :model="loginForm"
          ref="formRef">
          <template #code>
            <a-row :gutter="8">
              <a-col :xl="17" :lg="17":md="15" :sm="15" :xs="15">
                <a-input
                  v-model:value="loginForm.code"
                  size="large"
                  :placeholder="'请输入验证码'"
                  :prefix="h(SafetyCertificateOutlined)"></a-input>
              </a-col>
              <a-col :xl="7" :lg="7" :md="9" :sm="9" :xs="9">
                <a-image
                  :src="codeImg"
                  :preview="false"
                  style="border-radius: 4px; height: 40px"
                  @click="captcha" />
              </a-col>
            </a-row>
          </template>
        </u-form>

        <!-- 短信表单 -->
        <u-form
          :elements="smsFormEls"
          :model="smsForm"
          v-if="loginType == 1"
          ref="formRef">
          <template #code>
            <a-row :gutter="8">
              <a-col :span="24">
                <a-input-search
                  v-model:value="smsForm.code"
                  size="large"
                  placeholder="请输入短信验证码"
                  :prefix="h(SafetyCertificateOutlined)">
                  <template #enterButton>
                    <template v-if="smsTime > 0">{{ smsTime }}s</template>
                    <a-button
                      v-else
                      @click="getSurplus">
                      获取验证码
                    </a-button>
                  </template>
                </a-input-search>
              </a-col>
            </a-row>
          </template>
          <template #info>
            <a-row class="f-w-100">
              <a-alert
                class="f-w-100"
                message="暂未完成对接"
                type="warning" />
            </a-row>
          </template>
        </u-form>

        <u-icon-button
          :loading="loading"
          block
          size="large"
          @click="logingSubmit">
          登录
        </u-icon-button>
        <a-row>
          <span class="u-copyright-text">Copyright ©2024 QuanTumn. All Rights Reserved</span>
        </a-row>
      </div>
    </a-layout-content>
  </a-layout>
</template>

<script lang="ts" setup>
import { ref, reactive, computed, onMounted, h, onUnmounted } from "vue";
import { storeToRefs } from "pinia";
import { useHomeStore, useLoginStore, useEmergencyStore, useBaseStore } from "@/store";
import { useRoute, useRouter } from "vue-router";
import { isValue, urlFile } from "@/util/common";
import { FormInstance, FormItemProps } from "ant-design-vue";
import * as loginApi from "@/service/login";
import { checkUpdate } from "@/views/login/getVerision.js";
import useInitBaseData from "@/hooks/useInitBaseData.ts";
import { UserOutlined, LockOutlined, SafetyCertificateOutlined } from "@ant-design/icons-vue";
import { alertC, messageC } from "@/util/common";

const homeStore = useHomeStore();
const baseStore = useBaseStore();
const loginStore = useLoginStore();
const { sysName } = storeToRefs(homeStore);
const { smsTime } = storeToRefs(loginStore);

const emergencyStore = useEmergencyStore();
const router = useRouter();

onMounted(() => {
  captcha();
  getSurplus(true);
  homeStore.setTabMenu([]);
  homeStore.setFlatMenus([]);
  homeStore.setActiveTabMenu("0");
  loginStore.setIsMustChange(false);
  emergencyStore.setLevel("");
});

let loginBg = ref<{
  img: string;
  justify: string;
  snc: string;
  loginClass: string;
}>({
  img: urlFile("login/loginBg1.png"),
  justify: "center",
  snc: "#fff",
  loginClass: "u-login-box-fff",
});

// 1 短信登录   2 账号密码
const loginType = ref<string>("2");

// 验证码
const formRef = ref(null);
const codeImg = ref<string>("");
const loading = ref<boolean>(false);
const formItemProps: FormItemProps & _IExtra = {
  labelWidth: "0",
  colon: false,
};
const loginForm = reactive({
  account: "",
  password: "",
  code: "",
  grantType: "password",
  refreshToken: "",
  clientType: "web",
});
const loginFormEls = [
  {
    label: "",
    key: "account",
    col: { span: 24 },
    element: "input",
    formItemProps: { ...formItemProps, required: true },
    componentProps: {
      placeholder: "请输入登录名",
      size: "large",
      prefix: h(UserOutlined),
    },
  },
  {
    label: "",
    key: "password",
    col: { span: 24 },
    element: "password",
    formItemProps: { ...formItemProps, required: true },
    componentProps: { placeholder: "请输入密码", size: "large", autocomplete: "new-password", prefix: h(LockOutlined) },
  },
  {
    label: "",
    key: "code",
    col: { span: 24 },
    element: "slot",
    formItemProps: { ...formItemProps, required: true },
    componentProps: { placeholder: "请输入密码", size: "large" },
  },
];

const smsForm = reactive({
  tel: "",
  code: "",
});
const smsFormEls = [
  {
    label: "",
    key: "tel",
    col: { span: 24 },
    element: "input",
    formItemProps: { ...formItemProps, required: true },
    componentProps: {
      placeholder: "请输入手机号码",
      size: "large",
      prefix: h(UserOutlined),
    },
  },
  {
    label: "",
    key: "code",
    col: { span: 24 },
    element: "slot",
    formItemProps: { ...formItemProps, required: true },
    componentProps: { placeholder: "请输入短信验证码", size: "large" },
  },
  { label: "", key: "info", col: { span: 24 }, element: "slot" },
];

// 登录
const logingSubmit = async () => {
  try {
    await formRef.value.form.validate();
  } catch (error) {
    messageC("请先将登录信息填写完毕！");
    return;
  }

  // 验证验证码
  try {
    const checkCode = await loginApi.check({ key: codeKey.value, code: loginForm.code });
    if (checkCode.code != 0) {
      messageC(checkCode.msg);
      captcha();
      return;
    }
  } catch (error) {
    return;
  }

  loading.value = true;
  try {
    const res = await loginApi.login(loginForm);
    if (res.code == 0) {
      loginStore.setToken(res.data.token);
      loginStore.setRefreshToken(res.data.refreshToken);
      loginStore.setUserInfo(res.data);

      // 是否强制修改密码
      let mustChangePass = res.data.extra["change"] ? res.data.extra["change"] : false;
      loginStore.setIsMustChange(mustChangePass);

      router.replace({
        path: "/TransitIndex",
        params: {
          from: "index",
        },
      });

      // 初始化基础数据
      const { getAllBase } = useInitBaseData({
        userData: res.data || {},
      });
      getAllBase();
    } else {
      captcha();
      messageC(res.msg);
    }
  } catch (error) {}
  loading.value = false;
};

// 获取验证码
let codeKey = ref<number>();
const captcha = async () => {
  try {
    codeKey.value = Math.floor(Math.random() * 10000);
    const res = await loginApi.captcha(codeKey.value);
    let blob = new Blob([res.data]);
    codeImg.value = URL.createObjectURL(blob);
  } catch (error) {}
};

// 获取倒数短信剩余时间
let smsTimer = null;
const getSurplus = (isInit?: boolean) => {
  let surplusNum = 0;
  if (isInit == true) {
    surplusNum = smsTime.value <= 0 ? 0 : smsTime.value;
  } else {
    surplusNum = 60;
  }
  if (surplusNum > 0)
    smsTimer = setInterval(() => {
      surplusNum -= 1;
      loginStore.setSmsTime(surplusNum);
      if (surplusNum <= 0) {
        clearInterval(smsTimer);
      }
    }, 1000);
};

onUnmounted(() => {
  if (smsTimer) {
    clearInterval(smsTimer);
  }
});
</script>
<style lang="scss">
.u-login-container {
  width: 100vw;
  height: 100vh;
  background-size: 100% 100%;
  .u-sys-name-zh {
    font-family: Alimama ShuHeiTi, Alimama ShuHeiTi;
    font-weight: 700;
    font-size: 32px;
    line-height: 39px;
    text-align: left;
    font-style: normal;
    text-transform: none;
    background: linear-gradient(90deg, #9fd1ff 0%, #1890ff 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: var(--snc);
  }

  .u-sys-name-en {
    font-family: Nunito, Nunito;
    font-weight: 400;
    font-size: 12px;
    color: #999999;
    line-height: 16px;
    letter-spacing: 1px;
    text-align: left;
    font-style: normal;
    text-transform: none;
  }

  .u-login-box-fff {
    width: 6.5rem;
    min-width: 380px;
    max-width: 520px;
    margin: 0 auto;
    padding: 50px 56px;
    background: #fff;
    box-shadow: 0px 4px 10px 0px rgba(24, 144, 255, 0.1);
    border-radius: 8px 8px 8px 8px;
    box-sizing: border-box;

    .u-login-type-title {
      font-family: PingFang SC, PingFang SC;
      font-weight: 500;
      font-size: 20px;
      color: #666666;
      line-height: 28px;
      text-align: left;
      cursor: pointer;
    }

    .u-login-type-title-active {
      position: relative;
      font-size: 24px;
      color: #333333;
      font-weight: 600;

      &::after {
        content: "";
        position: absolute;
        bottom: -8px;
        left: 60%;
        transform: translatex(-60%);
        width: 50%;
        height: 4px;
        background: #1890ff;
        border-radius: 4px 4px 0px 0px;
      }
    }

    .u-welcome-text {
      margin-bottom: 26px;
      font-family: PingFang SC, PingFang SC;
      font-weight: 400;
      font-size: 24px;
      color: #333;
    }

    .ant-form-item {
      margin-bottom: 40px;

      .ant-input-affix-wrapper {
        background: #fff !important;
      }

      .ant-form-item-control-input-content {
        border-radius: 8px 8px 8px 8px;

        .ant-input {
          background: #fff !important;
          color: #333;

          &::placeholder {
            color: rgba(0, 0, 0, 0.4);
          }
        }
      }

      .ant-input-affix-wrapper {
        .ant-input-prefix {
          color: #333;
        }
      }
    }

    .u-copyright-text {
      margin-top: 24px;
      font-family: Nunito, Nunito;
      font-weight: 400;
      font-size: 14px;
      color: #333;
    }
  }

  input:-webkit-autofill {
    background: transparent;
    background-image: none;
  }

  ::-webkit-input-placeholder {
    color: #999;
    font-size: 14px;
  }

  :-webkit-autofill {
    -webkit-transition-delay: 999999s;
    -webkit-transition: color 999999s ease-out, background-color unset 999999s ease-out;
  }
}
</style>
